iT邦幫忙

2021 iThome 鐵人賽

DAY 12
2
Modern Web

[ 重構倒數30天,你的網站不Vue白不Vue ] 系列 第 12

[重構倒數第19天] - i18n什麼的交給前端來處理吧(二) Vue3 載入Vue-i18n

  • 分享至 

  • xImage
  •  

前言

該系列是為了讓看過Vue官方文件或學過Vue但是卻不知道怎麼下手去重構現在有的網站而去規畫的系列文章,在這邊整理了許多我自己使用Vue重構很多網站的經驗分享給讀者們。

在前一篇我們已經說到我們可以透過 Nodejs 來抓取 google sheet 裡面的內容來轉換我們前端要做多國語系所需要用到的 JSON 檔案,這次我們要在Vue的專案裡面來使用翻譯的 JSON 檔案。

還沒看過的走這邊 : https://ithelp.ithome.com.tw/articles/10262354

mike vue

首先我們會需要用到 vue-i18n 這個套件來幫助我們把網站變成多國語系,幫我npm安裝它

npm install vue-i18n@next -S

這邊要特別注意,如果你在網路上面搜尋 vue-i18n 可能會搜尋到 v8 的版本,那沒有支援 vue3,所以我們安裝的vue-i18n@next 是 v9 的版本,是給 Vue3 使用的,不過我在寫這篇文章的時候 v9 目前處於 v9.2.0-beta.2 的狀態,所以之後安裝的時候要稍微注意一下喔,安裝好了之後可以把我們處理過的翻譯檔案連同 language 資料夾一起搬到專案裡面。

其實可以把寫好的 GoogleSheetToJson.js 這個檔案一起搬入專案裡面,開一個 script 的資料夾來放。

然後在我們的 main.js 來引入 vue-i18n,像是下面這樣。

import { createApp } from "vue";
import { createI18n } from "vue-i18n";
import App from "./App.vue";
import zh from "./language/zh-TW.json";
import en from "./language/en-US.json";
import ja from "./language/ja-JP.json";
const i18n = createI18n({
  legacy: false,
  locale: "zh-TW",
  fallbackLocale: "zh-TW",
  messages: {
    "zh-TW": zh,
    "en-US": en,
    "ja-JP": ja
  }
});
createApp(App).use(i18n).mount("#app");

這邊有一個地方一定要特別注意,在使用 Vue I18n Composition API 的時候,一定要在 createI18n 設定裡面把 legacy 設成 false 才可以使用。

官方文件:https://vue-i18n.intlify.dev/guide/advanced/composition.html#basic-usage

都設定好了之後我們就直接來看一下 component 的部分

<script>
import { useI18n } from "vue-i18n";
export default {
  name: "App",
  setup() {
    const { t, locale } = useI18n();
    return {
      t,
      locale,
    };
  },
};
</script>

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <nav>
    <select v-model="locale">
      <option>zh-TW</option>
      <option>en-US</option>
      <option>ja-JP</option>
    </select>
  </nav>
  <p>{{ t("cancel") }}</p>
  <p>{{ t("email") }}</p>
  <p>{{ t("date") }}</p>
  <p>{{ t("subject") }}</p>
  <p>{{ t("message") }}</p>
  <p>{{ t("upload") }}</p>
</template>

首先我在 setup 裡面把 useI18n 裡面的 t 這個方法給取出來丟到 template 上面,這個函式可以對應你 JSON的key來把相對應的內容給取出來,再來我設定了一個 select 的下拉選單,透過 useI18n 裡面的 locale來綁定 select,讓他可以在切換的時候,直接幫我切換語系,不會重整頁面。

vue i18n mike

但是這樣還沒完.這個時候假設我們選取了其他語系,然後重新整理網頁,這個時候它就會切回我們的預設語系,這邊我預設是 zh-TW ,所以網頁 reload 的時候就會變中文的,所以接下來我們要來處理一下這個語系儲存的部分,其實這有很多種的做法,有的是由後端去儲存現在user所選取的語系,然後我們抓回來後在給予設定,又或是切換語系的時候我們來改變使用者的網址,在他的 domain 上面加入zh-TW或是en-US等字串來判斷他當前的語系,今天要來做一個比較簡單且通用的方式,就是把目前的語系寫入到我們的 localstorage 裡面,然後畫面 reload 的時候再把它給取出來設定就好了。

首先我們先watch一下

<script>
import { watch } from "vue";
import { useI18n } from "vue-i18n";
export default {
  name: "App",
  setup() {
    const { t, locale } = useI18n();

    watch(locale, (newlocale) => {
      localStorage.setItem("locale", newlocale);
    });

    return {
      t,
      locale,
    };
  },
};
</script>

我們 watch 了 locale,只要我一改變 locale 就會執行 watch ,然後把 newlocale 給塞入 localStorage 裡面,所以每一次只要改變了語系我們的 localStorage 裡面的這個 locale 就會是我們選擇的語系。

再來回到 main.js,修改一下我們在處理初始化的語系這邊

const i18n = createI18n({
  legacy: false,
  locale: localStorage.getItem("locale") ?? "zh-TW",
  fallbackLocale: "zh-TW",
  messages: {
    "zh-TW": zh,
    "en-US": en,
    "ja-JP": ja
  }
});

這邊你會看到我在這邊取得 localStorage 裡面的 locale,如果沒有這個 localStorage 的話就給他一個預設值 zh-TW,所以每一次頁面重新整理的時候就會拿到目前存入 localStorage 的語系,而初始化那個語系。

關於 ?? 的這個語法,它其實是ES11的語法 Nullish coalescing operator中文翻譯叫做 空值合併運算符,它是一個簡單的語法,當左側的 value 為 null 或者 undefined 時,它就會 return 右側 value,不然就 return 左側 value

MDN文件可以參考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

這個範例我有放到 codesandbox 上面,有興趣的朋友可以上去看一下
https://codesandbox.io/s/vue3-i18n-j1nbt

Mike Vue

那如果對於Vue3不夠熟的話呢?

Ps. 購買的時候請登入或註冊該平台的會員,然後再使用下面連結進入網站點擊「立即購課」,這樣才可以讓我獲得更多的課程分潤,還可以幫助我完成更多豐富的內容給各位。

我有開設了一堂專門針對Vue3從零開始教學的課程,如果你覺得不錯的話,可以購買我課程來學習
https://hiskio.com/bundles/9WwPNYRpz?s=tc

那如果對於JS基礎不熟的朋友,我也有開設JS的入門課程,可以參考這個課程
https://hiskio.com/bundles/b9Rovqy7z?s=tc

訂閱Mike的頻道享受精彩的教學與分享

Mike 的 Youtube 頻道
Mike的medium
MIke 的官方 line 帳號,好友搜尋 @mike_cheng


上一篇
[重構倒數第20天] - i18n什麼的交給前端來處理吧(一) 把GoogleSheet文件轉成JSON文件
下一篇
[重構倒數第18天] - 我如何再Vue裡面使用axios有效管理API
系列文
[ 重構倒數30天,你的網站不Vue白不Vue ] 32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言